#ifndef __CHUNK_HH__
#define __CHUNK_HH__

#include <mc/types.h>
#include <mc/chunkid.h>
#include <mc/block.h>
#include <map>

namespace mc
{
#define CHUNK_SZIE 16
#define CHUNK_HEIGHT 128

//! @brief 区块类
class Chunk
{
    friend class Loader;

public:
    //! @brief 构造函数
    Chunk(const ChunkID& id);
    Chunk(int x, int y);
    ~Chunk() noexcept;

    //! @brief 绘制区块
    void draw();

    //! @brief 更新区块中方块的位置矩阵
    void updatePosition();

    //! @brief 放置方块
    void placeBlock(int64_t x, int64_t y, int64_t z, BlockType block, bool update);

    //! @brief 移除方块
    BlockType removeBlock(int64_t x, int64_t y, int64_t z, bool update);

    //! @brief 运算符重载
    bool operator == (const Chunk& that) const 
    { return this->_id == that._id; }

    bool operator != (const Chunk& that) const 
    { return this->_id != that._id; }

    bool operator > (const Chunk& that) const 
    { return this->_id > that._id; }

    bool operator < (const Chunk& that) const 
    { return this->_id < that._id; }

public:
    //! @brief 通过坐标计算区块 id
    static ChunkID getChunkID(int64_t x, int64_t z);

private:
    //! @brief 区块号
    ChunkID _id;
    //! @brief 区块数据
    vector3 _blockData;

    //! @brief 方块
    std::map<BlockType, Block*> _blocks;

public:
    //! @brief 返回方块类型
    BlockType getBlockType(int x, int y, int z) const
    { return this->_blockData[x][y][z]; }

    //! @brief 设置方块类型
    void setBlockType(int x, int y, int z, BlockType type)
    { this->_blockData[x][y][z] = type; }

    //! @brief 属性
    vector3& blockData()
    { return this->_blockData; }

    const ChunkID& getID()
    { return this->_id; }

    std::map<BlockType, Block*>& blocks() 
    { return this->_blocks; } 
};

}

#endif